#!/bin/bash
ROOT="$(pwd)"

arch="all"
url=
license=
depends=()
optdepends=()
makedepends=()
provides=()
conflicts=()
source=()
sha256sums=()


function prepare() {
  :
}
function build() {
  :
}
function package() {
  :
}


srcdir=$(realpath -m ./src)
pkgdir=$(realpath -m ./pkg)


# Simple check whether the DEBBUILD looks valid or not
debbuild_verify() {
  # Check required values
  if [[ -z ${pkgname+x} ]]; then
    echo "pkgname not set";
    exit 1;
  elif [[ -z ${pkgrel+x} ]]; then
    echo "pkgrel not set";
    exit 1;
  elif [[ -z ${pkgdesc+x} ]]; then
    echo "pkgdesc not set";
    exit 1;
  elif [[ -z ${pkgver+x} ]]; then
    echo "pkgver not set";
    exit 1;
  fi
}


# Check dependencies
function check_deps() {
  MISSING=()
  for pkg in "${makedepends[@]}"; do
    dpkg -s "${pkg}" > /dev/null 2>&1
    if [[ $? -ne 0 ]]; then
      MISSING+=("${pkg}")
    fi
  done

  for pkg in "${depends[@]}"; do
    dpkg -s "${pkg}" > /dev/null 2>&1
    if [[ $? -ne 0 ]]; then
      MISSING+=("${pkg}")
    fi
  done

  if [[ ${#MISSING[@]} -ne 0 ]]; then
    echo "The following packages are missing, please install them first:"
    echo ""
    echo "  ${MISSING[@]}"
    echo ""
    exit 1
  fi
}


function exit_on_error() {
  if [[ $? -ne 0 ]]; then
    echo "exit"
    exit 1
  fi
}


function clean() {
  rm -rf ${srcdir}
  rm -rf ${pkgdir}
}


function verify_checksum() {
  NAME="${1}"
  INDEX=${2}

  if [[ ${OPT_CHECKSUMS} -ne 1 ]]; then
    return 0
  fi

  SHASUM="${sha512sums[${INDEX}]}"
  if [[ "${SHASUM}" == "SKIP" ]]; then
    return 0
  fi
  CHECKSUM=($(sha512sum ${NAME}))
  if [[ "${CHECKSUM}" != "${SHASUM}" ]]; then
    echo "Checksum mismatch for ${NAME}"
    exit 1
  fi
  return 0
}


function print_help() {
  echo "makedeb.sh [options]"
  echo ""
  echo "Options:"
  echo "  -c, --clean"
  echo "  -C, --cleanbuild"
  echo "  -d, --nodeps"
  echo "  -e, --noextract"
  echo "  -o, --nobuild"
  echo "  --noprepare"
  echo "  --skipchecksums"
  echo ""
}


CUR_SOURCE=
CUR_SOURCE_URI=
CUR_SOURCE_NAME=
CUR_SOURCE_PROTO=
CUR_SOURCE_SCHEME=
CUR_SOURCE_OPTIONS=

function parse_current_source() {
  CUR_SOURCE_URI="${CUR_SOURCE##*+}"
  CUR_SOURCE_URI="${CUR_SOURCE_URI##*::}"
  CUR_SOURCE_NAME=""
  CUR_SOURCE_PROTO=""
  CUR_SOURCE_SCHEME="${CUR_SOURCE_URI%%://*}"
  CUR_SOURCE_OPTIONS=""

  if [[ "${CUR_SOURCE}" == *"::"* ]]; then
    CUR_SOURCE_NAME="${CUR_SOURCE%%+*}"
    CUR_SOURCE_NAME="${CUR_SOURCE_NAME%%::*}"
  fi

  if [[ "${CUR_SOURCE}" == *"+"* ]]; then
    CUR_SOURCE_PROTO="${CUR_SOURCE%%+*}"
    CUR_SOURCE_PROTO="${CUR_SOURCE_PROTO##*::}"
  fi

  if [[ "${CUR_SOURCE_SCHEME}" == "${CUR_SOURCE_URI}" ]]; then
    CUR_SOURCE_SCHEME=""
  fi

  # Local file
  if [[ "${CUR_SOURCE_SCHEME}" == "" && "${CUR_SOURCE_PROTO}" == "" ]]; then
    CUR_SOURCE_NAME="${CUR_SOURCE_URI}"
  fi

  # No name supplied
  if [[ "${CUR_SOURCE_NAME}" == "" ]]; then
    CUR_SOURCE_NAME="$(basename ${CUR_SOURCE_URI})"
    
  fi

  # Extra options (#branch=testing)
  if [[ "${CUR_SOURCE_NAME}" == *"#"* ]]; then
    CUR_SOURCE_OPTIONS="${CUR_SOURCE_NAME##*#}"
    CUR_SOURCE_NAME="${CUR_SOURCE_NAME%%#*}"  # remove options
  fi
}


# Options
OPT_PREPARE=1
OPT_EXTRACT=1
OPT_BUILD=1
OPT_CLEAN=0
OPT_CLEANBUILD=0
OPT_DEPS=1
OPT_CHECKSUMS=1


# Parse flags
while [[ $# -gt 0 ]]; do
  case $1 in
    -c|--clean)
      OPT_CLEAN=1
      shift
      ;;
    -C|--cleanbuild)
      OPT_CLEANBUILD=1
      shift
      ;;
    -d|--nodeps)
      OPT_DEPS=0
      shift
      ;;
    -e|--noextract)
      OPT_EXTRACT=0
      shift
      ;;
    -o|--nobuild)
      OPT_BUILD=0
      shift
      ;;
    --noprepare)
      OPT_PREPARE=0
      shift
      ;;
    --skipchecksums)
      OPT_CHECKSUMS=0
      shift
      ;;
    --help)
      print_help
      exit 0
      ;;
  esac
done


source DEBBUILD
debbuild_verify


if [[ ${OPT_DEPS} -eq 1 ]]; then
  check_deps
fi


# Clean build
if [[ ${OPT_CLEANBUILD} -eq 1 ]]; then
  rm -rf "${srcdir}"
  rm -rf "${pkgdir}"
fi


# Download and verify sources
for ((i=0; i<${#source[@]}; i++)); do
  echo ""
  CUR_SOURCE="${source[${i}]}"
  parse_current_source

  # File/directory already exists
  if [[ -d ${CUR_SOURCE_NAME} || -f ${CUR_SOURCE_NAME} ]]; then
    verify_checksum "${CUR_SOURCE_NAME}" ${i}
    continue
  fi

  # Git
  if [[ "${CUR_SOURCE_PROTO}" == "git" ]]; then
    GITEXTRA="${CUR_SOURCE_URI##*#}"
    URI="${CUR_SOURCE_URI%%#*}"
    GITARGS="--bare --depth 1"
    if [[ "${GITEXTRA}" != "" ]]; then
      GITKEY="${GITEXTRA%%=*}"
      GITVAL="${GITEXTRA##*=}"
      GITARGS="${GITARGS} --${GITKEY} ${GITVAL}"
    fi
    git clone ${GITARGS} "${URI}" "${CUR_SOURCE_NAME}"
    exit_on_error

  # Wget
  elif [[ "${CUR_SOURCE_SCHEME}" == "https" || "${CUR_SOURCE_SCHEME}" == "http" ]]; then
    wget -O "${CUR_SOURCE_NAME}" "${CUR_SOURCE_URI}"
    exit_on_error
  fi

  verify_checksum "${CUR_SOURCE_NAME}" ${i}

done


# Create 'src' and 'pkg' dirs
if [[ ! -d ${srcdir} ]]; then
  mkdir ${srcdir}
fi
if [[ ! -d ${pkgdir} ]]; then
  mkdir ${pkgdir}
fi


# Extract sources
if [[ ${OPT_EXTRACT} -eq 1 ]]; then
  cd ${srcdir}
  for ((i=0; i<${#source[@]}; i++)); do
    CUR_SOURCE="${source[${i}]}"
    parse_current_source

    if [[ "${CUR_SOURCE_PROTO}" == "git" ]]; then
      git clone ../"${CUR_SOURCE_NAME}" "${CUR_SOURCE_NAME}"
      exit_on_error
    else
      ln -s ../"${CUR_SOURCE_NAME}" ./"${CUR_SOURCE_NAME}"
      exit_on_error

      if [[ "${CUR_SOURCE_NAME}" == *.tar.gz ]]; then
        tar -xvzf "${CUR_SOURCE_NAME}"
        exit_on_error
      fi
    fi
  done
fi


# Set pkgver from pkgver() function
cd ${srcdir}
if [[ $(type -t pkgver) == function ]]; then
  pkgver=$(pkgver)
  exit_on_error
fi


# Prepare
if [[ ${OPT_PREPARE} -eq 1 ]]; then
  prepare
  exit_on_error
fi


# Build the sources
if [[ ${OPT_BUILD} -eq 1 ]]; then
  build
  exit_on_error
fi

# Package
package
exit_on_error

mkdir "${pkgdir}/DEBIAN"
echo "Package: ${pkgname}
Version: ${pkgver}
Maintainer: ${maintainer}
Depends: ${depends}
Architecture: ${arch}
Homepage: ${url}
Description: ${pkgdesc}" \
> "${pkgdir}/DEBIAN/control"

cd "${ROOT}"
dpkg --build "${pkgdir}"
exit_on_error

NEW_PKGNAME="${pkgname}-${pkgver}-${pkgrel}_${arch}.deb"
mv pkg.deb ${NEW_PKGNAME}
exit_on_error


if [[ ${OPT_CLEAN} -eq 1 ]]; then
  : # TODO
fi


echo "New package ready at ${NEW_PKGNAME}"


